import wx
import wx.richtext
try:
    from . import menu
except ImportError:
    import menu


class Book_text(wx.Panel):
    def __init__(self, parent, file_name, text_type, **k):
        wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
        tool = menu.MakeToolBar(self)
        bSizer = wx.BoxSizer( wx.VERTICAL )
        
        self.rtc = wx.richtext.RichTextCtrl(self)
        wx.CallAfter(self.rtc.SetFocus)
        self.rtc.BeginSuppressUndo()                        # 使用撤销
        self.rtc.BeginParagraphSpacing(0, 20)               # 段落间距
        self.rtc.BeginAlignment(wx.TEXT_ALIGNMENT_CENTRE)   # 使用对其
        self.rtc.BeginBold()                                # 使用粗体
        self.rtc.EndSuppressUndo()
        bSizer.Add( tool, 0, wx.EXPAND, 5 )
        bSizer.Add( self.rtc, 1, wx.EXPAND, 5 )
        self.SetSizer( bSizer )
        self.Layout()
        self.rtc.SetDropTarget(parent.FileDrop(parent))
        self.on_create(file_name)
        self.Bind(wx.EVT_CLOSE, self.on_close)
        tool.Realize()

    def on_close(self, eve):
        self.Destroy()

    def on_create(self, file_name):
        if file_name:
            with open(file_name, "r",encoding="utf-8") as f:
                self.rtc.SetValue(f.read())

    def _attr(self, stype):
        attr = wx.TextAttr()
        attr.SetFlags(stype)
        ip = self.rtc.GetInsertionPoint()
        if self.rtc.GetStyle(ip, attr):
            r = wx.richtext.RichTextRange(ip, ip)
            if self.rtc.HasSelection():
                r = self.rtc.GetSelectionRange()
            return r, attr
        return None, None

    def OnFileOpen(self, evt):
        wildcard, types = wx.richtext.RichTextBuffer.GetExtWildcard(save=False)
        dlg = wx.FileDialog(self, "Choose a filename", wildcard=wildcard, style=wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            if path:
                fileType = types[dlg.GetFilterIndex()]
                self.rtc.LoadFile(path, fileType)
        dlg.Destroy()

    def OnFileSave(self, evt):
        if not self.rtc.GetFilename():
            wildcard, types = wx.richtext.RichTextBuffer.GetExtWildcard(save=True)
            dlg = wx.FileDialog(self, "Choose a filename", wildcard=wildcard, style=wx.FD_SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                path = dlg.GetPath()
                if path:
                    fileType = types[dlg.GetFilterIndex()]
                    ext = wx.richtext.RichTextBuffer.FindHandlerByType(fileType).GetExtension()
                    if not path.endswith(ext):
                        path += '.' + ext
                    self.rtc.SaveFile(path, fileType)
            dlg.Destroy()
            return
        self.rtc.SaveFile()

    def OnBold(self, evt):
        self.rtc.ApplyBoldToSelection()

    def OnItalic(self, evt):
        self.rtc.ApplyItalicToSelection()

    def OnUnderline(self, evt):
        self.rtc.ApplyUnderlineToSelection()

    def OnAlignLeft(self, evt):
        self.rtc.ApplyAlignmentToSelection(wx.TEXT_ALIGNMENT_LEFT)

    def OnAlignRight(self, evt):
        self.rtc.ApplyAlignmentToSelection(wx.TEXT_ALIGNMENT_RIGHT)

    def OnAlignCenter(self, evt):
        self.rtc.ApplyAlignmentToSelection(wx.TEXT_ALIGNMENT_CENTRE)

    def OnIndentMore(self, evt):
        r, attr= self._attr(wx.TEXT_ATTR_LEFT_INDENT)
        if r:
            attr.SetLeftIndent(attr.GetLeftIndent() + 100)
            attr.SetFlags(wx.TEXT_ATTR_LEFT_INDENT)
            self.rtc.SetStyle(r, attr)

    def OnIndentLess(self, evt):
        r, attr = self._attr(wx.TEXT_ATTR_LEFT_INDENT)
        if attr and attr.GetLeftIndent() >= 100:
            attr.SetLeftIndent(attr.GetLeftIndent() - 100)
            attr.SetFlags(wx.TEXT_ATTR_LEFT_INDENT)
            self.rtc.SetStyle(r, attr)

    def OnParagraphSpacingMore(self, evt):
        r, attr = self._attr(wx.TEXT_ATTR_PARA_SPACING_AFTER)
        if r:
            attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20);
            attr.SetFlags(wx.TEXT_ATTR_PARA_SPACING_AFTER)
            self.rtc.SetStyle(r, attr)

    def OnParagraphSpacingLess(self, evt):
        r, attr = self._attr(wx.TEXT_ATTR_PARA_SPACING_AFTER)
        if r and attr.GetParagraphSpacingAfter() >= 20:
            attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20);
            attr.SetFlags(wx.TEXT_ATTR_PARA_SPACING_AFTER)
            self.rtc.SetStyle(r, attr)

    def OnLineSpacingSingle(self, evt):
        r, attr = self._attr(wx.TEXT_ATTR_LINE_SPACING)
        if r:
            attr.SetFlags(wx.TEXT_ATTR_LINE_SPACING)
            attr.SetLineSpacing(10)
            self.rtc.SetStyle(r, attr)

    def OnLineSpacingDouble(self, evt):
        r, attr = self._attr(wx.TEXT_ATTR_LINE_SPACING)
        if r:
            attr.SetFlags(wx.TEXT_ATTR_LINE_SPACING)
            attr.SetLineSpacing(20)
            self.rtc.SetStyle(r, attr)

    def OnFont(self, evt):
        if not self.rtc.HasSelection():
            return
        r = self.rtc.GetSelectionRange()
        fontData = wx.FontData()
        fontData.EnableEffects(False)
        attr = wx.TextAttr()
        attr.SetFlags(wx.TEXT_ATTR_FONT)
        if self.rtc.GetStyle(self.rtc.GetInsertionPoint(), attr):
            fontData.SetInitialFont(attr.GetFont())
        dlg = wx.FontDialog(self, fontData)
        if dlg.ShowModal() == wx.ID_OK:
            fontData = dlg.GetFontData()
            font = fontData.GetChosenFont()
            if font:
                attr.SetFlags(wx.TEXT_ATTR_FONT)
                attr.SetFont(font)
                self.rtc.SetStyle(r, attr)
        dlg.Destroy()

    def OnColour(self, evt):
        colourData = wx.ColourData()
        attr = wx.TextAttr()
        attr.SetFlags(wx.TEXT_ATTR_TEXT_COLOUR)
        if self.rtc.GetStyle(self.rtc.GetInsertionPoint(), attr):
            colourData.SetColour(attr.GetTextColour())
        dlg = wx.ColourDialog(self, colourData)
        if dlg.ShowModal() == wx.ID_OK:
            colourData = dlg.GetColourData()
            colour = colourData.GetColour()
            if colour:
                if not self.rtc.HasSelection():
                    self.rtc.BeginTextColour(colour)
                else:
                    r = self.rtc.GetSelectionRange()
                    attr.SetFlags(wx.TEXT_ATTR_TEXT_COLOUR)
                    attr.SetTextColour(colour)
                    self.rtc.SetStyle(r, attr)
        dlg.Destroy()

    def OnUpdateBold(self, evt):
        evt.Check(self.rtc.IsSelectionBold())

    def OnUpdateItalic(self, evt):
        evt.Check(self.rtc.IsSelectionItalics())

    def OnUpdateUnderline(self, evt):
        evt.Check(self.rtc.IsSelectionUnderlined())

    def OnUpdateAlignLeft(self, evt):
        evt.Check(self.rtc.IsSelectionAligned(wx.TEXT_ALIGNMENT_LEFT))

    def OnUpdateAlignCenter(self, evt):
        evt.Check(self.rtc.IsSelectionAligned(wx.TEXT_ALIGNMENT_CENTRE))

    def OnUpdateAlignRight(self, evt):
        evt.Check(self.rtc.IsSelectionAligned(wx.TEXT_ALIGNMENT_RIGHT))

    def ForwardEvent(self, evt):
        self.rtc.ProcessEvent(evt)



class FileDrop(wx.FileDropTarget):
    def __init__(self,windows):
        wx.FileDropTarget.__init__(self)



def main():
    app = wx.App()
    ex = wx.Frame(None)
    ex.FileDrop = FileDrop
    Book_text(ex, None, 69)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()